package cn.scau.server.service.impl;

import cn.scau.server.dto.PCLoginFormDTO;
import cn.scau.server.mapper.AdminMapper;
import cn.scau.server.pojo.Admin;
import cn.scau.server.service.PCUserService;
import cn.scau.server.utils.MobileUserutils;
import cn.scau.server.utils.PCUserutils;
import cn.scau.server.vo.AdminPermissionVO;
import cn.scau.server.vo.EmpPermissionVO;
import cn.scau.server.vo.ResultVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static cn.scau.server.utils.RedisConstants.*;

@Service
@Transactional
public class PCUserServiceImpl extends ServiceImpl<AdminMapper, Admin> implements PCUserService {
    @Autowired
    private AdminMapper adminMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //todo 但是目前这些做法都是比较危险的（）后面要做优化的，因为目前就是很直白地把所有东西都放在前端了
    @Override
    public ResultVO login(PCLoginFormDTO loginForm, HttpSession session) {
        String account = loginForm.getAccount();
        String password = loginForm.getPassword();
        String redisKey = LOGIN_CODE_KEY + account;
        String redisPassword = stringRedisTemplate.opsForValue().get(redisKey);

        if (redisPassword != null) {
            if (!redisPassword.equals(password)) {
                return ResultVO.fail("账号密码不匹配");
            }
        } else {
            AdminPermissionVO admin = adminMapper.getAdminPermission(account);
            if (admin == null) {
                return ResultVO.fail("此管理员账号不存在！");
            }
            // todo 缓存穿透要小心
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account", account);
            Admin adminRecord = getOne(queryWrapper);
            if (adminRecord == null || !adminRecord.getPassword().equals(password)) {
                return ResultVO.fail("密码不正确！");
            }
        }

        // 生成登录令牌
        AdminPermissionVO admin = adminMapper.getAdminPermission(account);
        String token = PCUserutils.generateAdminToken();
        Map<String, Object> userMap = PCUserutils.adminToMap(admin);

        //清空过期token
        clearToken(account);

        // 存储用户信息和密码到 Redis
        stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + token, userMap);
        stringRedisTemplate.opsForValue().set(redisKey, password);

        // 设置 Redis 过期时间

        stringRedisTemplate.expire(LOGIN_USER_KEY + token, LOGIN_USER_TTL, TimeUnit.DAYS);
        stringRedisTemplate.expire(redisKey, LOGIN_CODE_TTL, TimeUnit.DAYS);

        return ResultVO.success("登录成功！", token);
    }

    private void clearToken(String account) {
        // 清理旧的Token
        Set<String> keys = stringRedisTemplate.keys(LOGIN_USER_KEY + "*");
        if (keys != null) {
            for (String key : keys) {
                Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);
                if (userMap != null && account.equals(userMap.get("account"))) {
                    stringRedisTemplate.delete(key); // 删除旧的Token
                }
            }
        }
    }

    @Override
    public ResultVO getAdminInfo(String account) {
        String key = LOGIN_USER_KEY + account;
        HashOperations<String, String, Object> hashOperations = stringRedisTemplate.opsForHash();

        // 尝试从 Redis 中获取用户信息
        Map<String, Object> adminMap = hashOperations.entries(key);
        System.out.println("adminMap: "+adminMap);
        if (adminMap != null && !adminMap.isEmpty()) {
            // 如果 Redis 中存在用户信息，直接返回
            AdminPermissionVO admin = (AdminPermissionVO) adminMap.get(key);
            System.out.println("Redis 中存在用户信息，admin: "+admin);
            return ResultVO.success("查询成功", admin);
        } else {
            // 如果 Redis 中不存在，从数据库中获取
            AdminPermissionVO admin = adminMapper.getAdminPermission(account);
            System.out.println("Redis 中不存在用户信息，admin: "+admin);
            if (admin == null) {
                // 如果数据库中也不存在，返回错误信息
                return ResultVO.fail("用户不存在");
            }
            // 将用户信息存储到 Redis 中，并设置有效期
            System.out.println("PCUserutils.adminToMap(admin): "+PCUserutils.adminToMap(admin));
            hashOperations.putAll(key, PCUserutils.adminToMap(admin));
            stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.DAYS);

            return ResultVO.success("查询成功", admin);
        }
    }
}
